home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-09-30 | 24.8 KB | 835 lines | [TEXT/MPS ] |
- {---------------------------------------------------------------------
- #
- # Apple Macintosh Developer Technical Support
- #
- # MultiFinder-Aware Simple TextEdit Sample Application
- #
- # OOPTESample
- #
- # UTEDocument.inc1.p - Pascal Source
- #
- # Copyright © 1988, 1989 Apple Computer, Inc.
- # All rights reserved.
- #
- # Version:
- # 1.10 10/89
- # 1.00 04/89
- #
- # Components:
- # BuildOOPTESample October 1, 1989
- # MOOPTESample.p October 1, 1989
- # OOPTESample.make October 1, 1989
- # TECommon.h October 1, 1989
- # TESampleGlue.a October 1, 1989
- # TESample.r October 1, 1989
- # UApplication.p October 1, 1989
- # UApplication.inc1.p October 1, 1989
- # UDocument.p October 1, 1989
- # UDocument.inc1.p October 1, 1989
- # UTEDocument.p October 1, 1989
- # UTEDocument.inc1.p October 1, 1989
- # UTESample.p October 1, 1989
- # UTESample.inc1.p October 1, 1989
- #
- ---------------------------------------------------------------------}
-
- CONST
- kTextMargin = 2; {kTextMargin is the number of pixels we leave
- blank at the edge of the window.}
-
- kMaxDocWidth = 576; {kMaxDocWidth is an arbitrary number used to specify
- the width of the TERec's destination rectangle so that
- word wrap and horizontal scrolling can be demonstrated.}
-
-
- kMinDocDim = 64; {kMinDocDim is used to limit the minimum dimension
- of a window when GrowWindow is called.}
-
-
- kControlInvisible = 0;
- kControlVisible = $FF; {kControlInvisible is used to 'turn off' controls
- (i.e., cause the control not to be redrawn as a result
- of some Control Manager call such as SetCtlValue)
- by being put into the contrlVis field of the record.
- kControlVisible is used the same way to 'turn on'
- the control.}
-
- kScrollbarWidth = 16; {kScrollBarAdjust and kScrollBarWidth are used in
- calculating values for control positioning and sizing.}
- kScrollbarAdjust = kScrollbarWidth - 1;
- kGrowboxAdjust = 15;
-
- kScrollTweek = 2; {kScrollTweek compensates for off-by-one requirements
- of the scrollbars to have borders coincide with the
- growbox.}
-
- kCRChar = chr(13);
- kDelChar = chr(8); {kCrChar is used to match with a carriage return
- when calculating the number of lines in the TextEdit
- record. kDelChar is used to check for delete in
- keyDowns.}
-
- kButtonScroll = 4; {kButtonScroll is how many pixels to scroll horizontally
- when the button part of the horizontal scrollbar is
- pressed.}
-
-
- kMaxTELength = 32000; {kMaxTELength is an arbitrary number used to limit
- the length of text in the TERec so that various errors
- won't occur from too many characters in the text.}
-
- kTESlop = 1024; { provides some extra security when pre-flighting
- edit commands. }
-
- rVScroll = 128; { vertical scrollbar control }
- rHScroll = 129; { horizontal scrollbar control }
-
- kTEDocErrStrings = 129; { id of our STR# for error strings }
-
- { The following are indicies into STR# resources. }
- eNoMemory = 1;
- eNoSpaceCut = 2;
- eNoCut = 3;
- eNoCopy = 4;
- eExceedPaste = 5;
- eNoSpacePaste = 6;
- eNoWindow = 7;
- eExceedChar = 8;
- eNoPaste = 9;
-
- (********************************************************************************************)
- (* G l o b a l R o u t i n e s *)
- (********************************************************************************************)
- (*
- Routines used by this class, which don't belong to the class since we use
- them as toolbox filter routines, and you cannot pass class methods as ProcPtrs.
- *)
-
-
- PROCEDURE AsmClikLoop; EXTERNAL;
-
- { Common algorithm for pinning the value of a control. It returns the actual amount }
- { the value of the control changed. }
-
- {$S Main}
- PROCEDURE CommonAction(control:ControlHandle; VAR amount:integer);
- VAR
- value, max: integer;
- BEGIN
- value := GetCtlValue(control);
- max := GetCtlMax(control);
- amount := value - amount;
- IF (amount <= 0) THEN
- amount := 0
- ELSE IF (amount >= max) THEN
- amount := max;
- SetCtlValue(control, amount);
- amount := value - amount; { calculate true change }
- END; { CommonAction }
-
-
- { Determines how much to change the value of the vertical scrollbar by and how }
- { much to scroll the TE record.}
-
- {$S Main}
- PROCEDURE VActionProc(control:ControlHandle;part:integer);
- VAR
- amount:integer;
- window:WindowPtr;
- hTE:TEHandle;
- doc:TTEDocument;
- BEGIN
- IF (part <> 0) THEN BEGIN
- window := control^^.contrlOwner;
- doc := TTEDocument(gApplication.DocList.FindDoc(window));
- hTE := doc.GetTEHandle;
- CASE part OF
- inUpButton, inDownButton: { one line }
- amount := 1;
- inPageUp, inPageDown: { one page }
- WITH hTE^^,viewRect DO
- amount := (bottom - top) DIV lineHeight;
- END;
- IF ((part = inDownButton) OR (part = inPageDown)) THEN
- amount := -amount; { reverse direction for a downer }
- CommonAction(control, amount);
- IF (amount <> 0) THEN
- TEScroll(0, amount*hTE^^.lineHeight, hTE);
- END;
- END; { VActionProc }
-
- { Determines how much to change the value of the horizontal scrollbar by and how }
- { much to scroll the TE record. }
-
- {$S Main}
- PROCEDURE HActionProc(control:ControlHandle;part:integer);
- VAR
- amount:integer;
- window:WindowPtr;
- hTE:TEHandle;
- doc:TTEDocument;
- BEGIN
- IF (part <> 0) THEN BEGIN
- window := control^^.contrlOwner;
- doc := TTEDocument(gApplication.DocList.FindDoc(window));
- hTE := doc.GetTEHandle;
- CASE part OF
- inUpButton, inDownButton: { a few pixels }
- amount := kButtonScroll;
- inPageUp, inPageDown: { a page width }
- WITH hTE^^.viewRect DO
- amount := (right - left);
- END;
- IF ((part = inDownButton) OR (part = inPageDown)) THEN
- amount := -amount; { reverse direction }
- CommonAction(control, amount);
- IF (amount <> 0) THEN
- TEScroll(amount, 0, hTE);
- END;
- END; { HActionProc }
-
- { Gets called from our assembly language routine, AsmClikLoop, which in turn }
- { is called by the TEClick toolbox routine. Saves the window's clip region, }
- { sets it to the portRect, adjusts the scrollbar values to match the TE scroll }
- { amount, then restores the clip region. }
-
- {$S Main}
- PROCEDURE PascalClikLoop;
- VAR
- region: RgnHandle;
- wind: WindowPtr;
- doc: TTEDocument;
- BEGIN
- wind := FrontWindow;
- doc := TTEDocument(gApplication.DocList.FindDoc(wind));
- region := NewRgn;
- GetClip(region); { save the old clip }
- ClipRect(wind^.portRect); { set the new clip }
- doc.AdjustScrollValues(FALSE); { pass false for canRedraw }
- SetClip(region); { restore the old clip }
- DisposeRgn(region);
- END; { PascalClikLoop }
-
- { Gets called from our assembly language routine, AsmClikLoop, which is in }
- { turn called by the TEClick toolbox routine. It returns the address of the }
- { default clikLoop routine that was put into the TERec by TEAutoView to }
- { AsmClikLoop so that it can call it. }
-
- {$S Main}
- FUNCTION GetOldClikLoop:ProcPtr;
- VAR
- doc: TTEDocument;
- BEGIN
- doc := TTEDocument(gApplication.DocList.FindDoc(FrontWindow));
- IF (doc = NIL) THEN
- GetOldClikLoop := nil
- ELSE
- GetOldClikLoop := doc.GetClikLoop;
- END; { GetOldClikLoop }
-
-
- (********************************************************************************************)
- (* T T E D o c u m e n t *)
- (********************************************************************************************)
-
- {$S Initialize}
- {-----------------------------------+
- | ITEDocument |
- +-----------------------------------}
- PROCEDURE TTEDocument.ITEDocument(resID:integer);
- VAR
- good:Boolean;
- destRect, viewRect: Rect;
- BEGIN
-
- IDocument(resID);
-
- SetPort(fDocWindow);
- GetTERect(viewRect);
- destRect := viewRect;
- destRect.right := destRect.left + kMaxDocWidth;
- fDocTE := TENew(destRect, viewRect);
-
- good := (fDocTE <> NIL); { if TENew succeeded, we have a good document. }
- IF good THEN BEGIN { good document? — get scrollbars }
- AdjustViewRect;
- TEAutoView(TRUE, fDocTE);
- fDocClik := fDocTE^^.clikLoop;
- fDocTE^^.clikLoop := @AsmClikLoop;
- fDocVScroll := GetNewControl(rVScroll, fDocWindow);
- good := (fDocVScroll <> NIL);
- END;
- IF good THEN BEGIN
- fDocHScroll := GetNewControl(rHScroll, fDocWindow);
- good := (fDocHScroll <> NIL);
- END;
-
- IF good THEN BEGIN { good? — adjust & draw the controls, draw the window }
- AdjustScrollValues(FALSE);
- ShowWindow(fDocWindow);
- END ELSE BEGIN { tell user we failed }
- AlertUser(kTEDocErrStrings,eNoWindow);
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | Free |
- +-----------------------------------}
- PROCEDURE TTEDocument.Free; OVERRIDE;
- BEGIN
- HideWindow(fDocWindow);
- IF fDocTE <> NIL THEN
- TEDispose(fDocTE); { dispose the TEHandle if we got far enough to make one }
- IF fDocVScroll <> NIL THEN
- DisposeControl(fDocVScroll);
- IF fDocHScroll <> NIL THEN
- DisposeControl(fDocHScroll);
- INHERITED Free;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoZoom |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoZoom(partCode:integer); OVERRIDE;
- BEGIN
- EraseRect(fDocWindow^.portRect);
- ZoomWindow(fDocWindow, partCode, (fDocWindow = FrontWindow));
- ResizeWindow; {after this, only thing valid is scrollbars.}
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoGrow |
- +-----------------------------------}
-
- {Called when a mouseDown occurs in the grow box of an active window. In
- order to eliminate any 'flicker', we want to invalidate only what is
- necessary. Since ResizeWindow invalidates the whole portRect, we save
- the old TE viewRect, intersect it with the new TE viewRect, and
- remove the result from the update region. However, we must make sure
- that any old update region that might have been around gets put back.}
-
- PROCEDURE TTEDocument.DoGrow(theEvent:EventRecord); OVERRIDE;
- VAR
- growResult: longint;
- tempRect: Rect;
- tempRgn: RgnHandle;
-
- PROCEDURE GetLocalUpdateRgn(aRgn:RgnHandle);
- BEGIN
- CopyRgn(WindowPeek(fDocWindow)^.updateRgn, aRgn); {save old update region}
- WITH fDocWindow^.portBits.bounds DO
- OffsetRgn(aRgn, left, top); {convert to local coords}
- END;
-
- BEGIN
- tempRect := screenBits.bounds;
- tempRect.left := kMinDocDim;
- tempRect.top := kMinDocDim;
- growResult := GrowWindow(fDocWindow, theEvent.where, tempRect);
- { see if it really changed size }
- IF growResult <> 0 THEN BEGIN
- tempRect := fDocTE^^.viewRect;
- tempRgn := NewRgn;
- GetLocalUpdateRgn(tempRgn);
- SizeWindow(fDocWindow, LoWrd(growResult), HiWrd(growResult), TRUE);
- ResizeWindow; {after this, only thing valid is scrollbars.}
- IF SectRect(tempRect, fDocTE^^.viewRect, tempRect) THEN;
- ValidRect(tempRect);
- InvalRgn(tempRgn);
- DisposeRgn(tempRgn);
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoContent |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoContent(theEvent:EventRecord); OVERRIDE;
- VAR
- mouse: Point;
- control: ControlHandle;
- part,value: integer;
- shiftDown: Boolean;
- BEGIN
- SetPort(fDocWindow);
- mouse := theEvent.where; { get the click position }
- GlobalToLocal(mouse);
- part := FindControl(mouse, fDocWindow, control);
- CASE part OF
- 0: BEGIN { not in a control }
- { see if we need to extend the selection }
- shiftDown := BAnd(theEvent.modifiers, shiftKey) <> 0; { extend if Shift is down }
- TEClick(mouse, shiftDown, fDocTE);
- END;
- inThumb: BEGIN
- value := GetCtlValue(control);
- part := TrackControl(control, mouse, NIL);
- IF part <> 0 THEN BEGIN
- value := value - GetCtlValue(control);
- { value now has CHANGE in value; if value changed, scroll }
- IF value <> 0 THEN BEGIN
- IF control = fDocVScroll THEN BEGIN
- TEScroll(0, value * fDocTE^^.lineHeight, fDocTE);
- END ELSE BEGIN
- TEScroll(value, 0, fDocTE);
- END;
- END;
- END;
- END;
- OTHERWISE BEGIN { they clicked in an arrow, so track & scroll }
- IF control = fDocVScroll THEN BEGIN
- value := TrackControl(control, mouse, @VActionProc);
- END ELSE BEGIN
- value := TrackControl(control, mouse, @HActionProc);
- END;
- END;
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoKeyDown |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoKeyDown(theEvent:EventRecord); OVERRIDE;
- VAR
- key: char;
- BEGIN
- IF BAnd(theEvent.modifiers, cmdKey) <> 1 THEN BEGIN { don't process command characters }
- key := char(BAnd(theEvent.message, charCodeMask));
- { we have a char. for our window; see if we are still below TextEdit’s }
- { limit for the number of characters }
- WITH fdocTE^^ DO BEGIN
- IF ((key = kDelChar) OR ((teLength - selEnd - selStart) + 1 < kMaxTELength)) THEN BEGIN
- TEKey(key, fDocTE);
- AdjustScrollbars(FALSE);
- AdjustTE;
- END ELSE BEGIN
- AlertUser(kTEDocErrStrings,eExceedChar);
- END;
- END;
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoActivate |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoActivate(becomingActive:Boolean); OVERRIDE;
- VAR
- tempRgn: RgnHandle;
- clipRgn: RgnHandle;
- growRect: Rect;
- BEGIN
- IF becomingActive THEN BEGIN
-
- { since we don’t want TEActivate to draw a selection in an area where }
- { we’re going to erase and redraw, we’ll clip out the update region }
- { before calling it. }
- tempRgn := NewRgn;
- clipRgn := NewRgn;
- { save old update region }
- CopyRgn(WindowPeek(fDocWindow)^.updateRgn, tempRgn);
- { put it in local coords }
- WITH fDocWindow^.portBits.bounds DO
- OffsetRgn(tempRgn, left, top);
- GetClip(clipRgn);
- { subtract updateRgn from clipRgn }
- DiffRgn(clipRgn, tempRgn, tempRgn);
- { make it the new clipRgn }
- SetClip(tempRgn);
- TEActivate(fDocTE);
- { restore the full-blown clipRgn }
- SetClip(clipRgn);
- { get rid of temp regions }
- DisposeRgn(tempRgn);
- DisposeRgn(clipRgn);
-
- { the controls must be redrawn on activation: }
- fDocVScroll^^.contrlVis := kControlVisible;
- fDocHScroll^^.contrlVis := kControlVisible;
- InvalRect(fDocVScroll^^.contrlRect);
- InvalRect(fDocHScroll^^.contrlRect);
- { the growbox needs to be redrawn on activation: }
- growRect := fDocWindow^.portRect;
- { adjust for the scrollbars }
- WITH growRect DO BEGIN
- top := bottom - kScrollbarAdjust;
- left := right - kScrollbarAdjust;
- END;
- InvalRect(growRect);
- END ELSE BEGIN { becoming Inactive }
- TEDeactivate(fDocTE);
- { the controls must be hidden on deactivation: }
- HideControl(fDocVScroll);
- HideControl(fDocHScroll);
- { we draw grow icon immediately, since we deactivate controls }
- { immediately, and the update delay looks funny }
- DrawGrowIcon(fDocWindow);
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoIdle |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoIdle; OVERRIDE;
- BEGIN
- TEIdle(fDocTE);
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoUpdate |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoUpdate; OVERRIDE;
- BEGIN
- BeginUpdate(fDocWindow); { this sets up the visRgn }
- IF NOT EmptyRgn(fDocWindow^.visRgn) THEN { draw if updating needs to be done }
- DrawWindow;
- EndUpdate(fDocWindow);
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoCut |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoCut; OVERRIDE;
- VAR
- total, contig: longint;
- BEGIN
- IF (ZeroScrap = noErr) THEN BEGIN
- PurgeSpace(total, contig);
- IF (fDocTE^^.selEnd - fDocTE^^.selStart + kTESlop > contig) THEN BEGIN
- AlertUser(kTEDocErrStrings,eNoSpaceCut);
- END ELSE BEGIN
- TECut(fDocTE);
- IF (TEToScrap <> noErr) THEN BEGIN
- AlertUser(kTEDocErrStrings,eNoCut);
- IF Boolean(ZeroScrap) THEN;
- END;
- END;
- END;
- AdjustScrollbars(FALSE);
- AdjustTE;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoCopy |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoCopy; OVERRIDE;
- BEGIN
- IF (ZeroScrap = noErr) THEN BEGIN
- TECopy(fDocTE); { after copying, export the TE scrap }
- IF (TEToScrap <> noErr) THEN BEGIN
- AlertUser(kTEDocErrStrings,eNoCopy);
- IF Boolean(ZeroScrap) THEN;
- END;
- END;
- AdjustScrollbars(FALSE);
- AdjustTE;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoPaste |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoPaste; OVERRIDE;
- VAR
- aHandle: Handle;
- oldsize,
- newSize: longint;
- saveErr: OSErr;
- BEGIN
- IF (TEFromScrap = noErr) THEN BEGIN
- WITH fDocTE^^ DO BEGIN
- IF (TEGetScrapLen + (teLength - (selEnd - selStart)) > kMaxTELength) THEN BEGIN
- AlertUser(kTEDocErrStrings,eExceedPaste);
- END ELSE BEGIN
- aHandle := Handle(TEGetText(fDocTE));
- oldSize := GetHandleSize(aHandle);
- newSize := oldSize + TEGetScrapLen + kTESlop;
- SetHandleSize(aHandle, newSize);
- saveErr := MemError;
- SetHandleSize(aHandle, oldSize);
- IF (saveErr <> noErr) THEN BEGIN
- AlertUser(kTEDocErrStrings,eNoSpacePaste);
- END ELSE BEGIN
- TEPaste(fDocTE);
- END;
- END;
- END;
- END ELSE BEGIN
- AlertUser(kTEDocErrStrings,eNoPaste);
- END;
- AdjustScrollbars(FALSE);
- AdjustTE;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoClear |
- +-----------------------------------}
- PROCEDURE TTEDocument.DoClear; OVERRIDE;
- BEGIN
- TEDelete(fDocTE);
- AdjustScrollbars(FALSE);
- AdjustTE;
- END;
-
- {$S Main}
- {-----------------------------------+
- | HaveSelection |
- +-----------------------------------}
- FUNCTION TTEDocument.HaveSelection:Boolean; OVERRIDE;
- BEGIN
- IF (fDocTE^^.selStart < fDocTE^^.selEnd) THEN
- HaveSelection := TRUE
- ELSE
- HaveSelection := FALSE;
- END;
-
- {$S Main}
- {-----------------------------------+
- | CalcIdle |
- +-----------------------------------}
- FUNCTION TTEDocument.CalcIdle:Longint; OVERRIDE;
- BEGIN
- IF NOT(HaveSelection) THEN BEGIN
- CalcIdle := GetCaretTime;
- END ELSE BEGIN
- CalcIdle := $7FFFFFFF;
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustScrollValues |
- +-----------------------------------}
- { Simply call the common adjust routine for the vertical and horizontal scrollbars. }
- PROCEDURE TTEDocument.AdjustScrollValues(mustRedraw:Boolean);
- BEGIN
- AdjustHV(true, mustRedraw);
- AdjustHV(false, mustRedraw);
- END;
-
- {$S Main}
- {-----------------------------------+
- | GetClikLoop |
- +-----------------------------------}
- FUNCTION TTEDocument.GetClikLoop:ProcPtr;
- BEGIN
- GetClikLoop := fDocClik;
- END;
-
- {$S Main}
- {-----------------------------------+
- | GetTEHandle |
- +-----------------------------------}
- FUNCTION TTEDocument.GetTEHandle:TEHandle;
- BEGIN
- GetTEHandle := fDocTE;
- END;
-
- {$S Main}
- {-----------------------------------+
- | GetVisTERgn |
- +-----------------------------------}
- PROCEDURE TTEDocument.GetVisTERgn(rgn:RgnHandle);
- VAR
- teRect: Rect;
- BEGIN
- teRect := fDocTE^^.viewRect; { get a local copy of viewRect }
- SetPort(fDocWindow); { make sure we have right port }
- LocalToGlobal(teRect.topLeft);
- LocalToGlobal(teRect.botRight);
- RectRgn(rgn, teRect);
- { we temporarily change the port’s origin to “globalfy” the visRgn }
- WITH fDocWindow^.portbits.bounds DO
- SetOrigin(-left,-top);
- SectRgn(rgn, fDocWindow^.visRgn, rgn);
- SetOrigin(0, 0);
- END;
-
- {$S Main}
- {-----------------------------------+
- | GetTERect |
- +-----------------------------------}
- { Return a rectangle that is inset from the portRect by the size of }
- { the scrollbars and a little extra margin. }
- PROCEDURE TTEDocument.GetTERect(VAR teRect:Rect);
- BEGIN
- teRect := fDocWindow^.portRect;
- InsetRect(teRect, kTextMargin, kTextMargin); { adjust for margin }
- WITH teRect DO BEGIN
- bottom := bottom - kScrollbarAdjust; { and for the scrollbars }
- right := right - kScrollbarAdjust;
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustTE |
- +-----------------------------------}
- { Scroll the TERec around to match up to the potentially updated scrollbar }
- { values. This is really useful when the window has been resized such that the }
- { scrollbars became inactive but the TERec was already scrolled. }
- PROCEDURE TTEDocument.AdjustTE;
- BEGIN
- WITH fDocTE^^ DO BEGIN
- TEScroll((viewRect.left - destRect.left) - GetCtlValue(fDocHScroll),
- (viewRect.top - destRect.top) - (GetCtlValue(fDocVScroll) * lineHeight),
- fDocTE);
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DrawWindow |
- +-----------------------------------}
- PROCEDURE TTEDocument.DrawWindow;
- BEGIN
- SetPort(fDocWindow);
- EraseRect(fDocWindow^.portRect); { As per TextEdit chapter of Inside Macintosh }
- DrawControls(fDocWindow); { This ordering makes for a better appearance }
- DrawGrowIcon(fDocWindow);
- TEUpdate(fDocWindow^.portRect, fDocTE);
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustViewRect |
- +-----------------------------------}
- { Update the TERec's view rect so that it is the greatest multiple of }
- { the lineHeight that still fits in the old viewRect. }
- PROCEDURE TTEDocument.AdjustViewRect;
- BEGIN
- WITH fDocTE^^,fDocTE^^.viewRect DO BEGIN
- bottom := (((bottom - top) DIV lineHeight) * lineHeight) + top;
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | ResizeWindow |
- +-----------------------------------}
-
- {Called when the window has been resized to fix up the controls and content.
- This routine moves and resizes the scrollbars, adjusts their values, scrolls
- the TERecord in case we grew the window out from under it, invalidates the
- entire port, and then validates the areas under the scrollbars.}
-
- PROCEDURE TTEDocument.ResizeWindow;
- BEGIN
- AdjustScrollbars(TRUE); { adjust, redraw anyway }
- AdjustTE;
- InvalRect(fDocWindow^.portRect); { invalidate the whole content }
- { the scrollbars were taken care of by AdjustScrollbars, so validate ’em }
- ValidRect(fDocVScroll^^.contrlRect);
- ValidRect(fDocHScroll^^.contrlRect);
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustHV |
- +-----------------------------------}
- { Calculate the new control maximum value and current value, whether it is the horizontal or }
- { vertical scrollbar. The vertical max is calculated by comparing the number of lines to the }
- { vertical size of the viewRect. The horizontal max is calculated by comparing the maximum document }
- { width to the width of the viewRect. The current values are set by comparing the offset between }
- { the view and destination rects. If necessary, redraw the control by calling ShowControl. }
- PROCEDURE TTEDocument.AdjustHV(isVert, mustRedraw:Boolean);
- VAR
- value, lines, max: integer;
- oldValue, oldMax: integer;
- hTE: TEHandle;
- control: ControlHandle;
- BEGIN
- IF isVert THEN
- control := fDocVScroll
- ELSE
- control := fDocHScroll;
- oldValue := GetCtlValue(control);
- oldMax := GetCtlMax(control);
- hTE := fDocTE;
- WITH hTE^^ DO BEGIN
- IF isVert THEN BEGIN
- lines := nLines;
- { since nLines isn’t right if the last character is a return, check for that case }
- { MUST perform a short circuit check here, or we get a check error. }
- IF ((teLength > 0) & (CharsHandle(hText)^^[teLength-1] = kCrChar)) THEN
- lines := lines + 1;
- WITH viewRect DO max := lines - ((bottom - top) DIV lineHeight);
- END ELSE BEGIN
- WITH viewRect DO max := kMaxDocWidth - (right - left);
- END;
- END;
- IF max < 0 THEN max := 0;
- SetCtlMax(control, max);
-
- WITH hTE^^ DO BEGIN
- IF isVert THEN BEGIN
- value := (viewRect.top - destRect.top) DIV lineHeight
- END ELSE BEGIN
- value := viewRect.left - destRect.left;
- END;
- END;
-
- {Pin the value to within range}
- IF value < 0 THEN value := 0;
- IF value > max THEN value := max;
-
- SetCtlValue(control, value);
- { now redraw the control if asked to or if a setting changed }
- IF ((mustRedraw) OR ((max <> oldMax) OR (value <> oldValue))) THEN
- ShowControl(control);
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustScrollSizes |
- +-----------------------------------}
- { Re-calculate the position and size of the viewRect and the scrollbars. }
- { kScrollTweek compensates for off-by-one requirements of the scrollbars }
- { to have borders coincide with the growbox. }
- PROCEDURE TTEDocument.AdjustScrollSizes;
- VAR
- teRect: Rect;
- BEGIN
- GetTERect(teRect);
- fDocTE^^.viewRect := teRect;
- AdjustViewRect;
- WITH fDocWindow^.portRect DO BEGIN
- MoveControl(fDocVScroll, right - kScrollbarAdjust, -1);
- SizeControl(fDocVScroll, kScrollbarWidth, bottom - top - kGrowboxAdjust + kScrollTweek);
- MoveControl(fDocHScroll, -1, bottom - kScrollbarAdjust);
- SizeControl(fDocHScroll, right - left - kGrowboxAdjust + kScrollTweek, kScrollbarWidth);
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustScrollbars |
- +-----------------------------------}
- { Turn off the controls by jamming a zero into their contrlVis fields (HideControl erases them }
- { and we don't want that). If the controls are to be resized as well, call the procedure to do that, }
- { then call the procedure to adjust the maximum and current values. Finally re-enable the controls }
- { by jamming a $FF in their contrlVis fields (ShowControl re-draws the control, which may not be }
- { necessary). }
- PROCEDURE TTEDocument.AdjustScrollbars(needsResize:Boolean);
- BEGIN
- { First, turn visibility of scrollbars off so we won’t get unwanted redrawing }
- fDocVScroll^^.contrlVis := kControlInvisible;
- fDocHScroll^^.contrlVis := kControlInvisible;
- IF needsResize THEN BEGIN
- AdjustScrollSizes;
- END;
- AdjustScrollValues(needsResize);
- { Now, restore visibility in case we never had to draw during adjustment }
- fDocVScroll^^.contrlVis := kControlVisible;
- fDocHScroll^^.contrlVis := kControlVisible;
- END;
-